package com.zx.flow.api.util;

import com.alibaba.fastjson2.JSONArray;
import com.google.common.collect.Lists;
import com.zx.flow.api.config.FlowConfigOperator;
import com.zx.flow.api.dict.FlowDict.Event;
import com.zx.flow.api.dict.FlowDict.OperatorGetType;
import com.zx.flow.api.dict.FlowDict.OperatorRule;
import com.zx.flow.api.execute.common.Convert;
import com.zx.flow.api.execute.model.FlowContext;
import com.zx.flow.api.execute.model.FlowNode;
import com.zx.flow.api.execute.model.FlowOperator;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

@Slf4j
public class OperatorsUtil {

    public static List<FlowOperator> getOperator(FlowContext flow, FlowNode node, Event event,
            FlowConfigOperator config) {
        if (config == null) {
            return new ArrayList<>();
        }
        String type = config.getType();
        if (OperatorGetType.array.getCode().equals(type)) {
            log.info("process get operator, type=array, operator={}", config.getAccounts());
            return config.getAccounts();
        } else if (OperatorGetType.http.getCode().equals(type)) {
            // 调用http接口查询
            String body = SendUtil.httpPost(Convert.to(flow, node, event),
                    config.getUrl(), config.getConnectionTimeout(), config.getReadTimeout(), config.getReplay());
            JSONArray data = Util.getJsonObject(body).getJSONArray("data");
            List<FlowOperator> operators = data.toJavaList(FlowOperator.class);
            /*ArrayList<FlowOperator> operators = Lists.newArrayList(
                    new FlowOperator("zhangsan", "张三", OperatorRule.operator.getCode()),
                    new FlowOperator("lisi", "李四", OperatorRule.operator.getCode()));*/
            log.info("process get operator, type=http, operator={}", operators);
            return operators;
        }
        // 没有操作人的时候，给一个默认的人。比如system，只有system可以操作
        return Lists.newArrayList(getSystem());
    }

    /**
     * 获得系统权限【权限最大】
     *
     * @return
     */
    public static FlowOperator getSystem() {
        OperatorRule defOper = OperatorRule.system;
        return new FlowOperator(defOper.getCode(), defOper.getName(), defOper.getCode());
    }

    /**
     * 获得系统账号
     *
     * @return
     */
    public static String getSystemCode() {
        return getSystem().getAccountCode();
    }

    /**
     * 校验系统权限【rule是system】
     *
     * @return
     */
    public static boolean checkSystem(OperatorRule rule) {
        return Objects.equals(rule, OperatorRule.system);
    }

    /**
     * 校验系统权限【账号是system】
     *
     * @return
     */
    public static boolean checkSystem(String accountCode) {
        return Objects.equals(accountCode, getSystemCode());
    }

    /**
     * 校验系统权限【账号是system或者rule是system】
     *
     * @return
     */
    public static boolean checkSystem(FlowOperator operator) {
        return checkSystem(operator.getAccountCode()) || checkSystem(operator.getRule());
    }

    /**
     * 获得申请人
     *
     * @param flowContext
     * @return
     */
    public static FlowOperator getApply(FlowContext flowContext) {
        return new FlowOperator(flowContext.getApplyAccountCode(), "",
                OperatorRule.operator.getCode());
    }

    /**
     * 从列表中查询人员
     *
     * @param operators
     * @param findOperator
     * @return
     */
    public static FlowOperator find(List<FlowOperator> operators, String findOperator) {
        if (CollectionUtils.isEmpty(operators)) {
            return null;
        }
        for (FlowOperator operator : operators) {
            if (Objects.equals(operator.getAccountCode(), findOperator)) {
                return operator;
            }
        }
        return null;
    }

    /**
     * 判断是否所有人都通过[ProcessEvent.approved]
     *
     * @param nodes
     * @param currentNodeCode
     * @return
     */
    public static boolean isAllOperator(List<FlowNode> nodes, String currentNodeCode) {
        // 当前节点的所有所有节点
        List<FlowNode> currNodes = nodes.stream()
                .filter(node -> Objects.equals(currentNodeCode, node.getNodeCurrentCode()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(currNodes)) {
            return false;
        }
        // 获得当前节点-最新的所有审批人
        List<FlowOperator> operators = FlowDataUtil.getNodeByIdx(currNodes, nodes.size() - 1).getOperators();
        // 所有通过的节点,获得他的审批人
        Map<String, List<FlowNode>> operatorListMap = currNodes.stream()
                .filter(node -> Event.nodeApproved.getCode().equals(node.getEventCode()))
                .collect(Collectors.groupingBy(node -> node.getOperator().getAccountCode()));
        for (FlowOperator operator : operators) {
            if (!operatorListMap.containsKey(operator.getAccountCode())) {
                return false;
            }
        }
        return true;
    }

}
